package com.shiguiwu.springmybatis.mybatis;

import cn.hutool.core.map.MapUtil;
import com.shiguiwu.springmybatis.mybatis.mapper.BookMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: stone
 * @date: Created by 2021/6/23 23:38
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.mybatis
 */
@Slf4j
public class MapperTests {
    public static SqlSessionFactory FACTORY = null;

    static {
        try {
            FACTORY = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();

        }
    }

    public static void testSelect() {
        SqlSession sqlSession = FACTORY.openSession(true);
        BookMapper bookMapper = sqlSession.getMapper(BookMapper.class);
        List<Book> id = bookMapper.list(MapUtil.of("id", 1));
        System.out.println(id);
    }

    public static void testSql() {
        SqlSession sqlSession = FACTORY.openSession(true);
        BookMapper bookMapper = sqlSession.getMapper(BookMapper.class);
        String testSql = bookMapper.testSql("我是谁");
        System.out.println(testSql);
    }

    public static void mockMapper() {
        SqlSession sqlSession = FACTORY.openSession(true);
        BookMapper bookMapper = (BookMapper) Proxy.newProxyInstance(MapperTests.class.getClassLoader(),
                new Class[]{BookMapper.class}, new UserMapperProxy(sqlSession, BookMapper.class));
        List<Book> bookList = bookMapper.getBookList();
        System.out.println(bookList);
    }


    public static void batchInsert() {
        long s = System.currentTimeMillis();
        SqlSession sqlSession = FACTORY.openSession(true);
        BookMapper bookMapper = sqlSession.getMapper(BookMapper.class);
        int num = 1000000;
        List<Book> list = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            Book b = new Book();
            b.setBookName("name" + i);
            list.add(b);
        }

        bookMapper.insertBatch(list);
        log.info("{} 条费用 {}s",num,(System.currentTimeMillis() -s)/1000);
    }

    public static void batchInsertV2() {
        long s = System.currentTimeMillis();
        SqlSession sqlSession = FACTORY.openSession(ExecutorType.BATCH,false);
        BookMapper bookMapper = sqlSession.getMapper(BookMapper.class);
        int num = 1000000;
        //List<Book> list = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            Book b = new Book();
            b.setBookName("name" + i);
            //list.add(b);
            bookMapper.insert(b);
            if (i % 1000 == 999) {
                sqlSession.commit();
                sqlSession.clearCache();
            }

        }
        sqlSession.commit();
        sqlSession.clearCache();
        log.info("{} 条费用 {}s",num,(System.currentTimeMillis() -s)/1000);
    }

    public static void main(String[] args) {
        //testSelect();
//        mockMapper();
        testSql();
    }

    //模拟mybatis创建代理接口对象，调用方法

    public static class UserMapperProxy implements InvocationHandler {
        private SqlSession sqlSession;

        private Class<?> aClass;

        public UserMapperProxy(SqlSession sqlSession, Class<?> aClass) {
            this.sqlSession = sqlSession;
            this.aClass = aClass;
        }


        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            log.error("invoke start");
            String statement = aClass.getName() + "." + method.getName();
            List<Object> objects = sqlSession.selectList(statement);
            log.error("invoke end");
            return objects;
        }
    }


}
